namespace Example.Models
{
    using System;
    using System.Collections.Specialized;
    using System.Web;
    using Moq;
    using SimpleWebServices;
    using SimpleWebServices.Data;
    using SimpleWebServices.Models;
    using SimpleWebServices.Web;
    using SimpleWebServices.Web.UI.Html;
    using Xunit;

    public sealed class LogOnFormFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<LogOnForm>()
                .DerivesFrom<FormContainer>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .XmlRoot("container")
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new LogOnForm());
        }

        [Fact]
        public void op_Complete_FormSession()
        {
            FakeRepository.Clear();

            try
            {
                DateTimeFactory.Mock = DateTime.UtcNow;
                Token token = Token.New();

                FakeRepository.Register<RegisteredUser>(new
                {
                    token = Token.New(),
                    urn = "urn://user/john.doe@example.com",
                    xml =
                        "<user>" +
                            "<email address='john.doe@example.com' />" +
                            "<name salutation='Mr' given='John' family='Doe' />" +
                            "<roles>" +
                                "<role>Administrator</role>" +
                                "<role>Public</role>" +
                            "</roles>" +
                            "<password hash='EayiFl2Ny1C1Ri7CAAi+TVwUl/+zFCabS7zsq0Nppa4=' salt='Eajjf31MPFgt7g==' />" +
                        "</user>"
                });
                FakeRepository sessions = FakeRepository.Register<FormSession>(new
                {
                    token = token,
                    xml = "<session />"
                });

                FormSession session = new FormSession
                {
                    Token = token,
                    Urn = "urn://session/" + token,
                    Data = new DataCollection
                    {
                        { "email", "john.doe@example.com" }
                    }
                };

                var mock = new Mock<HttpContextBase>();
                mock.SetupGet<NameValueCollection>(x => x.Request.ServerVariables).Returns(new NameValueCollection { { "REMOTE_ADDR", "127.0.0.1" } }).Verifiable();
                mock.SetupGet<HttpCookieCollection>(x => x.Response.Cookies).Returns(new HttpCookieCollection()).Verifiable();
                HttpContextFactory.Mock = mock.Object;

                new LogOnForm().Complete(session);

                Assert.True((bool)sessions.Xml.CreateNavigator().Evaluate("1=count(/repository/object[@token][@urn]/session/data[@completed='true'])"));

                mock.VerifyAll();
            }
            finally
            {
                DateTimeFactory.Reset();
                HttpContextFactory.Reset();
                FakeRepository.Reset();
            }
        }

        [Fact]
        public void op_Complete_FormSessionNull()
        {
            Assert.Throws<ArgumentNullException>(() => new LogOnForm().Complete(null as FormSession));
        }

        [Fact]
        public void op_TemplateOfT()
        {
            Assert.NotNull(new LogOnForm().Template<LogOnForm>());
        }
    }
}